package com.xyy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.xyy.dto.ActivityCreateDTO;
import com.xyy.dto.ActivityUpdateDTO;
import com.xyy.entity.Activity;
import com.xyy.mapper.ActivityMapper;
import com.xyy.service.ActivityService;
import com.xyy.service.FileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;


import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 活动Service实现类
 */
@Slf4j
@Service
public class ActivityServiceImpl implements ActivityService {
    
    @Autowired
    private ActivityMapper activityMapper;
    
    @Autowired
    private FileService fileService;
    
    @Override
    public Activity createActivity(ActivityCreateDTO createDTO, Long adminId) {
        // 验证时间逻辑
        if (createDTO.getStartTime().isAfter(createDTO.getEndTime())) {
            throw new RuntimeException("开始时间不能晚于结束时间");
        }
        
        Activity activity = new Activity();
        BeanUtils.copyProperties(createDTO, activity);
        activity.setAdminId(adminId);
        // createdAt和updatedAt由MyBatis-Plus自动填充
        
        activityMapper.insert(activity);
        return activity;
    }
    
    @Override
    public boolean deleteActivity(Long activityId, Long adminId) {
        // 检查活动是否存在且属于当前管理员
        Activity activity = getActivityByIdAndAdminId(activityId, adminId);
        if (activity == null) {
            return false;
        }
        
        return activityMapper.deleteById(activityId) > 0;
    }
    
    @Override
    public Activity updateActivity(ActivityUpdateDTO updateDTO, Long adminId) {
        // 检查活动是否存在且属于当前管理员
        Activity existingActivity = getActivityByIdAndAdminId(updateDTO.getId(), adminId);
        if (existingActivity == null) {
            throw new RuntimeException("活动不存在或无权限修改");
        }
        
        // 验证时间逻辑
        if (updateDTO.getStartTime() != null && updateDTO.getEndTime() != null) {
            if (updateDTO.getStartTime().isAfter(updateDTO.getEndTime())) {
                throw new RuntimeException("开始时间不能晚于结束时间");
            }
        }
        
        Activity activity = new Activity();
        BeanUtils.copyProperties(updateDTO, activity);
        // updatedAt由MyBatis-Plus自动填充
        
        activityMapper.updateById(activity);
        return getActivityById(updateDTO.getId());
    }
    
    @Override
    public List<Activity> getActivityList() {
        QueryWrapper<Activity> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("created_at");
        
        return activityMapper.selectList(queryWrapper);
    }
    
    @Override
    public Activity getActivityById(Long activityId) {
        return activityMapper.selectById(activityId);
    }
    
    @Override
    public List<Activity> getActivityListByAdminId(Long adminId) {
        QueryWrapper<Activity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("admin_id", adminId);
        queryWrapper.orderByDesc("created_at");
        
        return activityMapper.selectList(queryWrapper);
    }
    
    @Override
    public String uploadCover(Long activityId, Long adminId, String filename, byte[] fileBytes) throws IOException {
        // 检查活动是否存在且属于当前管理员
        Activity activity = getActivityByIdAndAdminId(activityId, adminId);
        if (activity == null) {
            throw new RuntimeException("活动不存在或无权限修改");
        }
        
        // 上传文件到MinIO - 使用专门的封面上传方法
        String coverUrl = fileService.uploadCover(convertToMultipartFile(fileBytes, filename));
        
        // 更新活动封面
        updateActivityCover(activityId, adminId, coverUrl);
        
        return coverUrl;
    }
    
    @Override
    public void updateActivityCover(Long activityId, Long adminId, String coverUrl) {
        // 检查活动是否存在且属于当前管理员
        Activity activity = getActivityByIdAndAdminId(activityId, adminId);
        if (activity == null) {
            throw new RuntimeException("活动不存在或无权限修改");
        }
        
        LambdaUpdateWrapper<Activity> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Activity::getId, activityId)
                    .eq(Activity::getAdminId, adminId)
                    .set(Activity::getCover, coverUrl);
        
        activityMapper.update(null, updateWrapper);
        
        log.info("活动封面更新成功: activityId={}, adminId={}, coverUrl={}", activityId, adminId, coverUrl);
    }
    
    @Override
    public String refreshActivityCoverUrl(Long activityId) {
        try {
            Activity activity = activityMapper.selectById(activityId);
            if (activity == null || activity.getCover() == null || activity.getCover().isEmpty()) {
                return null;
            }
            
            // 从现有URL中提取对象名
            String objectName = fileService.extractObjectNameFromUrl(activity.getCover());
            if (objectName.isEmpty()) {
                return null;
            }
            
            // 生成新的预签名URL
            String newCoverUrl = fileService.generatePresignedUrl(objectName, "covers");
            
            // 更新数据库中的URL
            LambdaUpdateWrapper<Activity> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(Activity::getId, activityId)
                        .set(Activity::getCover, newCoverUrl);
            
            activityMapper.update(null, updateWrapper);
            
            log.info("活动封面URL刷新成功: activityId={}, newUrl={}", activityId, newCoverUrl);
            return newCoverUrl;
            
        } catch (Exception e) {
            log.error("刷新活动封面URL失败: activityId={}", activityId, e);
            return null;
        }
    }
    
    @Override
    public Resource getActivityCover(String filename) {
        try {
            return fileService.getFile(filename, "covers");
        } catch (Exception e) {
            log.error("获取活动封面失败: filename={}", filename, e);
            return null;
        }
    }
    
    /**
     * 根据ID和管理员ID获取活动
     * @param activityId 活动ID
     * @param adminId 管理员ID
     * @return 活动
     */
    private Activity getActivityByIdAndAdminId(Long activityId, Long adminId) {
        QueryWrapper<Activity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", activityId);
        queryWrapper.eq("admin_id", adminId);
        
        return activityMapper.selectOne(queryWrapper);
    }
    

    
    /**
     * 将byte[]转换为MultipartFile
     * @param fileBytes 文件字节数组
     * @param filename 文件名
     * @return MultipartFile对象
     */
    private MultipartFile convertToMultipartFile(byte[] fileBytes, String filename) {
        return new MultipartFile() {
            @Override
            public String getName() {
                return "cover";
            }

            @Override
            public String getOriginalFilename() {
                return filename;
            }

            @Override
            public String getContentType() {
                return "image/jpeg"; // 默认类型，可以根据文件扩展名动态设置
            }

            @Override
            public boolean isEmpty() {
                return fileBytes == null || fileBytes.length == 0;
            }

            @Override
            public long getSize() {
                return fileBytes != null ? fileBytes.length : 0;
            }

            @Override
            public byte[] getBytes() throws IOException {
                return fileBytes;
            }

            @Override
            public java.io.InputStream getInputStream() throws IOException {
                return new ByteArrayInputStream(fileBytes);
            }

            @Override
            public void transferTo(java.io.File dest) throws IOException, IllegalStateException {
                // 实现文件传输逻辑
                try (java.io.FileOutputStream fos = new java.io.FileOutputStream(dest)) {
                    fos.write(fileBytes);
                }
            }
        };
    }
} 